package com.rex.saas.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rex.saas.bean.DeviceBasicData;
import com.rex.saas.bean.DeviceTimeSeries;
import com.rex.saas.bean.response.AssetResponse;
import com.rex.saas.bean.response.DeviceDetailResponse;
import com.rex.saas.bean.response.DeviceResponse;
import com.rex.saas.bean.response.AssetDetailResponse;
import com.rex.saas.constants.Constants;
import com.rex.saas.db.entity.SaasSpaceDeviceRelation;
import com.rex.saas.db.entity.SaasStrategyTask;
import com.rex.saas.db.mapper.SaasSpaceDeviceRelationMapper;
import com.rex.saas.enums.DeviceTypeEnum;
import com.rex.saas.enums.StrategyTypeEnum;
import com.rex.saas.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName AssetService
 * @Description:
 * @Author: zhusiyu
 * @CreateDate: 2024/12/18 11:06	//创建时间
 */
@Component
@Slf4j
public class AssetService {

    @Autowired
    RexolarApiClient rexolarApiClient;

    @Autowired
    DeviceService deviceService;

    @Autowired
    SpaceService spaceService;

    @Autowired
    StrategyTaskService strategyTaskService;

    @Autowired
    SaasSpaceDeviceRelationMapper saasSpaceDeviceRelationMapper;

    private static final long ONLINE_MILLISECOND = 10 * 60 * 1000;

    public List<AssetResponse> list(String token) {
        return rexolarApiClient.getTenantAssetsInfo(token);
    }

    public List<DeviceDetailResponse> devices(String spaceId, String token) {
        List<DeviceDetailResponse> responseList = new ArrayList<>();
        String tenantId = JwtUtils.getTenantId(token);
        List<SaasSpaceDeviceRelation>  deviceList = getDeviceList(tenantId, spaceId);
        if(CollectionUtils.isEmpty(deviceList)){
            log.warn("devices deviceBasicDataList is empty, spaceInfoId:{}", spaceId);
            return responseList;
        }
        for (SaasSpaceDeviceRelation deviceBasicData : deviceList){
            DeviceBasicData deviceDetail = rexolarApiClient.getDeviceByDeviceName(deviceBasicData.getDeviceName(), token);
            if(deviceDetail==null){
                log.warn("device is empty, deviceName:{}", deviceBasicData.getDeviceName());
                continue;
            }
            DeviceDetailResponse response = deviceService.detail(deviceDetail,  token);
//            response.setDeviceId(deviceDetail.getCoreId());
//            response.setDeviceName(deviceDetail.getName());
//            response.setDeviceAlias(deviceDetail.getLabel());
//            response.setCategoryId(deviceDetail.getProfileId());
//            Map<String, String> deviceProfiles = rexolarApiClient.getDeviceProfiles(token);
//            String profileName = deviceProfiles.get(deviceDetail.getProfileId());
//            if(profileName!=null){
//                response.setCategoryName(profileName);
//                if(profileName.contains("网关")|| Constants.GW_ZIGBEE.equals(profileName)){
//                    response.setNodeType("gateway");
//                }else{
//                    response.setNodeType("device");
//                }
//            }
//            Map<String,Object> attributes = rexolarApiClient.getDeviceAttributes(deviceDetail.getCoreId(), token, new String[]{Constants.LAST_ACTIVITY_TIME,Constants.ACTIVE,Constants.ModelId});
//            Long now = System.currentTimeMillis();
//            if(attributes!=null){
//                Long lastActivityTime = attributes.get(Constants.LAST_ACTIVITY_TIME)==null? 0L : Long.valueOf(attributes.get(Constants.LAST_ACTIVITY_TIME).toString());
//                if(now - lastActivityTime > ONLINE_MILLISECOND){
//                    response.setStatus(0);
//                }else {
//                    response.setStatus(1);
//                }
//                response.setLastUpdateTime(Long.parseLong(attributes.get(Constants.LAST_ACTIVITY_TIME).toString()));
//                response.setModelId(attributes.get(Constants.ModelId)==null?"":attributes.get(Constants.ModelId).toString());
//                response.setModelName(DeviceService.getModelMap().get(response.getModelId()));
//            }

            responseList.add(response);
        }
        return responseList;
    }

    public AssetDetailResponse details(String spaceId, String token) {
        AssetDetailResponse assetDetailResponse = new AssetDetailResponse();
        String tenantId = JwtUtils.getTenantId(token);
        List<SaasSpaceDeviceRelation>  deviceList = getDeviceList(tenantId, spaceId);
        if(CollectionUtils.isEmpty(deviceList)){
            log.warn("details deviceBasicDataList is empty, spaceInfoId:{}", spaceId);
        }
        float power = 0F;
        Integer gwCnt = 0;
        Integer gwOnline = 0;
        Integer gwOffline = 0;
        Integer deviceCnt = 0;
        Integer deviceOnline = 0;
        Integer deviceOffline = 0;

        List<DeviceDetailResponse> deviceDetailResponses = new ArrayList<>();
        for (SaasSpaceDeviceRelation deviceBasicData : deviceList){
            DeviceBasicData deviceDetail = rexolarApiClient.getDeviceByDeviceName(deviceBasicData.getDeviceName(), token);
            if(deviceDetail==null){
                log.warn("device is empty, deviceName:{}", deviceBasicData.getDeviceName());
                continue;
            }
            DeviceDetailResponse  deviceDetailResponse = deviceService.detail(deviceDetail, token);
            if("gateway".equals(deviceDetailResponse.getNodeType())){
                gwCnt++;
                if (deviceDetailResponse.getStatus()==1){
                    gwOnline++;
                }else {
                    gwOffline++;
                }
            }else {
                deviceCnt++;
                if (deviceDetailResponse.getStatus()==1){
                    deviceOnline++;
                }else {
                    deviceOffline++;
                }
            }
//            Map<String,Object> attributes = rexolarApiClient.getDeviceAttributes(deviceDetail.getCoreId(), token,
//                    new String[]{Constants.LAST_ACTIVITY_TIME,Constants.ACTIVE,Constants.ModelId,"SubDevices","Power_Consumption_1",Constants.DEV_STATUS});
//            if(attributes!=null){
//                response.setLastUpdateTime(Long.parseLong(attributes.get(Constants.LAST_ACTIVITY_TIME).toString()));
//                response.setModelId(attributes.get(Constants.ModelId)==null?"":attributes.get(Constants.ModelId).toString());
//                response.setModelName(DeviceService.getModelMap().get(response.getModelId()));
//                response.setSubDevices(attributes.get("SubDevices")==null?"":attributes.get("SubDevices").toString());
//                if(attributes.get("Power_Consumption_1")!=null){
//                    power =+ Float.parseFloat(attributes.get("Power_Consumption_1").toString());
//                }
//            }else {
//                log.warn("device attributes deviceId:{} not found", deviceBasicData.getDeviceName());
//                continue;
//            }
//            if(DeviceTypeEnum.GATEWAY.getCode().equals(deviceBasicData.getType())){
//                response.setStatus("true".equals(attributes.get(Constants.ACTIVE).toString())?1:0);
//                response.setCategoryName("gateway");
//                response.setNodeType("gateway");
//                gwCnt++;
//                if (response.getStatus()==1){
//                    gwOnline++;
//                }else {
//                    gwOffline++;
//                }
//            }else {
//                response.setNodeType("device");
//                response.setCategoryName(DeviceService.getModelMap().get(response.getModelId()));
//                deviceCnt++;
//            }
//            response.setCategoryId(deviceDetail.getProfileId());
//            response.setDeviceId(deviceDetail.getCoreId());
//            response.setDeviceName(deviceDetail.getName());
//            response.setDeviceAlias(deviceDetail.getLabel());
//            response.setCategoryId(deviceDetail.getProfileId());
//
//            Map<String, List<DeviceTimeSeries>> deviceTimeSeriesMap = rexolarApiClient.getDeviceTimeSeriesLatest(deviceDetail.getCoreId(), token, new String[]{},false);
//            List<Map<String, String>> latestTimeSeries = new ArrayList<>();
//            for(String key : deviceTimeSeriesMap.keySet()){
//                Map<String, String> map = new HashMap<>();
//                List<DeviceTimeSeries> values = deviceTimeSeriesMap.get(key);
//                JSONObject jsonObject = JSONObject.parseObject(values.get(0).toJSONString());
//                map.put("value", jsonObject.getString("value"));
//                map.put("key", key);
//                latestTimeSeries.add(map);
//            }
//            response.setLatestTimeSeries(latestTimeSeries);
            deviceDetailResponses.add(deviceDetailResponse);
        }
        assetDetailResponse.setDevices(deviceDetailResponses);
        assetDetailResponse.setDeviceCnt(deviceCnt);
        assetDetailResponse.setDeviceOnline(deviceOnline);
        assetDetailResponse.setDeviceOffline(deviceOffline);
        assetDetailResponse.setGwCnt(gwCnt);
        assetDetailResponse.setGwOnline(gwOnline);
        assetDetailResponse.setGwOffline(gwOffline);

        List<SaasStrategyTask> tasks = strategyTaskService.listBySpaceId(spaceId, tenantId);
        int cnt3 = 0;
        int cnt2 = 0;
        int cnt1 = 0;
        for (SaasStrategyTask task : tasks){
            if(StrategyTypeEnum.LINK.getCode().equals(task.getType())){
                cnt3++;
            }else if(StrategyTypeEnum.TIMER.getCode().equals(task.getType())){
                cnt2++;
            }else if(StrategyTypeEnum.ONE_CLICK.getCode().equals(task.getType())){
                cnt1++;
            }
        }
        assetDetailResponse.setTimeStrategyCnt(cnt2);
        assetDetailResponse.setLinkStrategyCnt(cnt3);
        assetDetailResponse.setOneClickStrategyCnt(cnt1);
        assetDetailResponse.setPower(power);
        return assetDetailResponse;
    }

    public boolean addAssetDevices(String tenantId, String assetId, String deviceName) {
        LambdaQueryWrapper<SaasSpaceDeviceRelation> allQueryWrapper = new LambdaQueryWrapper<>();
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getDeviceName, deviceName);
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getTenantId, tenantId);
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getSpaceId, assetId);
        List<SaasSpaceDeviceRelation> list = saasSpaceDeviceRelationMapper.selectList(allQueryWrapper);
        if(!list.isEmpty()){
            return true;
        }
        SaasSpaceDeviceRelation saasSpaceDeviceRelation = new SaasSpaceDeviceRelation();
        saasSpaceDeviceRelation.setTenantId(tenantId);
        saasSpaceDeviceRelation.setSpaceId(assetId);
        saasSpaceDeviceRelation.setDeviceName(deviceName);
        return saasSpaceDeviceRelationMapper.insert(saasSpaceDeviceRelation)==1;
    }

    public boolean deleteDevice(String tenantId, String deviceName) {
        LambdaQueryWrapper<SaasSpaceDeviceRelation> allQueryWrapper = new LambdaQueryWrapper<>();
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getTenantId, tenantId);
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getDeviceName, deviceName);
        List<SaasSpaceDeviceRelation> list = saasSpaceDeviceRelationMapper.selectList(allQueryWrapper);
        if(list.isEmpty()){
            return true;
        }
        return saasSpaceDeviceRelationMapper.delete(allQueryWrapper)>0;
    }

    public List<SaasSpaceDeviceRelation> getDeviceList(String tenantId, String assetId) {
        LambdaQueryWrapper<SaasSpaceDeviceRelation> allQueryWrapper = new LambdaQueryWrapper<>();
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getTenantId, tenantId);
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getSpaceId, assetId);
        return saasSpaceDeviceRelationMapper.selectList(allQueryWrapper);
    }

    public IPage<SaasSpaceDeviceRelation> selectPage(Integer pageNo, Integer pageSize, String tenantId, String assetId) {
        Page<SaasSpaceDeviceRelation> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<SaasSpaceDeviceRelation> queryWrapper = new LambdaQueryWrapper<SaasSpaceDeviceRelation>();
        queryWrapper.eq(SaasSpaceDeviceRelation::getTenantId, tenantId);
        queryWrapper.eq(SaasSpaceDeviceRelation::getSpaceId, assetId);
        return saasSpaceDeviceRelationMapper.selectPage(page, queryWrapper);
    }

    public List<SaasSpaceDeviceRelation> getAssetByDevice(String tenantId, String deviceName) {
        LambdaQueryWrapper<SaasSpaceDeviceRelation> allQueryWrapper = new LambdaQueryWrapper<>();
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getTenantId, tenantId);
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getDeviceName, deviceName);
        return saasSpaceDeviceRelationMapper.selectList(allQueryWrapper);
    }

    public boolean unbindAssetDevices(String tenantId, String assetId, String deviceName) {
        LambdaQueryWrapper<SaasSpaceDeviceRelation> allQueryWrapper = new LambdaQueryWrapper<>();
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getDeviceName, deviceName);
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getTenantId, tenantId);
        allQueryWrapper.eq(SaasSpaceDeviceRelation::getSpaceId, assetId);
        List<SaasSpaceDeviceRelation> list = saasSpaceDeviceRelationMapper.selectList(allQueryWrapper);
        if(list.isEmpty()){
            return true;
        }
        return saasSpaceDeviceRelationMapper.delete(allQueryWrapper) > 0;
    }
}
